import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import { message } from 'antd';
import { ApiResponse, ValidationError } from '@/api/types';

// 创建 axios 实例
const request: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL || '/dev',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
  },
});

// 请求拦截器
request.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    // 从localStorage获取token
    const token = localStorage.getItem('token');
    if (token && config.headers) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 处理验证错误
const handleValidationErrors = (errors: ValidationError[]) => {
  if (errors && errors.length > 0) {
    // 显示第一个错误信息
    const firstError = errors[0];
    message.error(firstError.msg);
    
    // 如果有多个错误，在控制台输出所有错误
    if (errors.length > 1) {
      console.warn('验证错误详情:', errors);
    }
  }
};

// 响应拦截器
request.interceptors.response.use(
  (response: AxiosResponse<ApiResponse>) => {
    const { data } = response;
    // 只要 http 200，业务 success false 也要统一抛出错误
    if (response.status === 200) {
      if (data.success === false) {
        // 判断是否未认证相关
        const isAuthError = data.message?.includes('未登录') || data.message?.includes('未验证') || data.message?.includes('未授权');
        const error: any = new Error(data.message || '操作失败');
        error.code = isAuthError ? 401 : 500;
        return Promise.reject(error);
      }
      return response;
    }
    return Promise.reject(new Error(data.message || 'Error'));
  },
  (error) => {
    if (error.response) {
      const { status, data } = error.response;
      switch (status) {
        case 401:
          localStorage.removeItem('token');
          localStorage.removeItem('userInfo');
          message.error('登录已过期，请重新登录');
          break;
        case 500:
          message.error(data?.message || '服务器内部错误');
          break;
        case 400:
          if (data.errors && data.errors.length > 0) {
            handleValidationErrors(data.errors);
          } else {
            message.error(data?.message || '请求参数错误');
          }
          break;
        case 403:
          message.error('没有权限访问该资源');
          break;
        case 404:
          message.error('请求的资源不存在');
          break;
        case 422:
          if (data.errors && data.errors.length > 0) {
            handleValidationErrors(data.errors);
          } else {
            message.error(data?.message || '数据验证失败');
          }
          break;
        default:
          message.error(data?.message || '请求失败');
      }
    } else if (error.request) {
      message.error('网络错误，请检查网络连接');
    } else {
      message.error('请求配置错误');
    }
    return Promise.reject(error);
  }
);

// 提取API响应数据的工具函数
export const extractApiData = <T>(response: AxiosResponse<ApiResponse<T>>): T => {
  return response.data.data as T;
};

// 封装 GET 请求
export const get = <T = any>(url: string, params?: any, config?: AxiosRequestConfig) => {
  return request.get<ApiResponse<T>>(url, { params, ...config }).then(extractApiData);
};

// 封装 POST 请求
export const post = <T = any>(url: string, data?: any, config?: AxiosRequestConfig) => {
  return request.post<ApiResponse<T>>(url, data, config).then(extractApiData);
};

// 封装 PUT 请求
export const put = <T = any>(url: string, data?: any, config?: AxiosRequestConfig) => {
  return request.put<ApiResponse<T>>(url, data, config).then(extractApiData);
};

// 封装 DELETE 请求
export const del = <T = any>(url: string, config?: AxiosRequestConfig) => {
  return request.delete<ApiResponse<T>>(url, config).then(extractApiData);
};

export default request; 